package com.yyk.dzvisit.core.aop;

import com.yyk.dzvisit.enums.RequestContextEnum;
import com.yyk.dzvisit.vo.ApiResponse;
import com.yyk.dzvisit.vo.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @author : ligui
 * @date : Created in 2020/11/24
 */
@Aspect
@Component
@Slf4j
public class ControllerInterceptor {

    @Autowired
    private HttpServletRequest request;

    @Pointcut("execution (* com.yyk.*.controller..*Controller.*(..))")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        beforeInterceptorLog(pjp);
        Object result = pjp.proceed();
        String token = RequestContext.getContext()
                .getContextDetail(RequestContextEnum.HX_RETURN_TOKEN.name());
        if (result != null
                && result instanceof ApiResponse
                && StringUtils.isNotBlank(token)) {
            ApiResponse apiResponse = (ApiResponse) result;
            apiResponse.setToken(token);
            result = apiResponse;
        }
        afterInterceptorLog(pjp, result);
        return result;
    }


    /**
     * 拦截器前打LOG的工具类
     *
     * @param pjp
     */
    private void beforeInterceptorLog(ProceedingJoinPoint pjp) {
        try {
            String className = pjp.getTarget().getClass().getSimpleName();
            String methodName = pjp.getSignature().getName();
            Signature signature = pjp.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("uri[").append(request.getRequestURI()).append("], ");
            stringBuilder.append("ip[").append(IpUtil.getRequestIp(request)).append("], ");
            stringBuilder.append("method[").append(className).append("@").append(methodName)
                    .append("] ");

            for (int i = 0; i < pjp.getArgs().length; i++) {
                stringBuilder.append("参数名:");
                stringBuilder.append(methodSignature.getParameterNames()[i]);
                stringBuilder.append(",参数值:");
                stringBuilder.append(pjp.getArgs()[i]);
            }
            log.info(stringBuilder.toString());
        } catch (Exception e) {
            log.error("打印日志异常", e);
        }
    }

    /**
     * 拦截器后打LOG的工具类
     *
     * @param pjp
     */
    private void afterInterceptorLog(ProceedingJoinPoint pjp, Object result) {
        try {
            String className = pjp.getTarget().getClass().getSimpleName();
            String methodName = pjp.getSignature().getName();
            log.info(StringUtils
                    .join("method[", className, "@", methodName, "], 结果为: ", result));
        } catch (Exception e) {
            log.error("打印日志异常", e);
        }
    }

}
